#!/usr/bin/python
# -*- coding: UTF-8 -*-

import sys,os,yaml,time,json
import sqlite3

'''
使用方法:

1. 在此功能包cfg/logdb_extract.yaml配置文档中, 模块名称和节点列表, 其中模块名称可自定义, 但节点名称需要与数据库中一致

格式示例如下：
-------
# 报警功能相关
alarm_manager:  
  node_list:
    - "/power_monitor_node"
    - "/alarm_upload_node"
-------

2. 日志目录logs_dir和输出目录output_dir可在cfg/logdb_extract.yaml文档中进行配置


3. 通过指令运行脚本, 同时传入参数 模块名称 起始时间 结束时间，

指令示例如下：
    cd /home/aoting/hrg_bee_dev_v3/src/test_module/helper/scripts
    python helper_logdb_extract.py alarm_manager "2023-08-16 11:12:22" "2023-08-16 11:12:23"

运行结束后, 会提示文件保存路径
-------
......
[Extract] find 199 rows.
[Extract] finished. output_filepath: /home/aoting/user_config/logs/2023-08-18_15:27:26_alarm_manager.log
-------
'''

class DbEXtract:
    def __init__(self, moudle, start_time, end_time):
        self.__config_yaml = "/home/aoting/hrg_bee_dev_v3/src/test_module/helper/cfg/logdb_extract.yaml"
        self.__moudle = moudle
        self.__start_time = start_time
        self.__end_time = end_time
        print("[params] moudle: {}, start_time: {}, end_time: {}".format(self.__moudle, self.__start_time, self.__end_time))  
        self.Extract()  
    
    def getYamlData(self, file_path):
        '''
            description: 获取配置文件
            param {*} self
            param {*} file_path 配置文件路径
            return {*}
        '''    
        try:
            yaml_data = dict()
            if not os.path.exists(file_path):
                raise Exception("please check config_yaml. path: {}".format(file_path))
            with open(file_path, "r") as file:
                yaml_data = yaml.load(file, yaml.SafeLoader)    
                for key,value in yaml_data.items():
                    # print(key,value, type(value))
                    if value == "dict":
                        print("[getYamlData] moudle: <{}>, node_list: {}".format(key, value["node_list"]))
                    else:
                        print("[getYamlData] {}:{}".format(key,value))
            return yaml_data       
        except Exception as error:
            print("[getYamlData] error: {}".format(error))
            return yaml_data
    
    def generateSqlCommand(self, node_list):
        ''' 生成查询指令
        '''
        print("---------------[generateSqlCommand]---------------")
        # print(node_list)
        sql_cmd = '''SELECT node_name,log_time,save_time,log_data FROM log_save WHERE (save_time >= "'''
        sql_cmd += self.__start_time
        sql_cmd += '''" AND save_time <="'''
        sql_cmd += self.__end_time
        sql_cmd += '''" ) AND node_name IN ('''
        for i in range(len(node_list)):
            sql_cmd += '''"{}"'''.format(node_list[i])
            if i< len(node_list)-1:
                sql_cmd += ","
            else:
                sql_cmd += ")"
        return sql_cmd
          
    def Extract(self):
        '''开始提取文件
        '''
        try:
            now_timeArray = time.localtime(time.time())
            now_timeStr = time.strftime("%Y-%m-%d_%H:%M:%S", now_timeArray)
            print(now_timeStr)

            # 获取参数配置文件
            print("---------------[getYamlData]---------------")
            yaml_data = self.getYamlData(self.__config_yaml)  
            if not yaml_data: return  
            logs_dir = yaml_data["logs_dir"]
            output_dir = yaml_data["output_dir"]
            output_filepath = "{}/{}_{}.log".format(output_dir,now_timeStr,self.__moudle)
            db_filepath = "{}/logs.db".format(logs_dir)
            print("---------------[Extract]---------------")
            print("[Extract] db_filepath: {}".format(db_filepath))  
            print("[Extract] output_filepath: {}".format(output_filepath)) 

            # 校验路径和数据
            if not os.path.exists(db_filepath):
                raise Exception("db_filepath does not exist.")
            if self.__moudle not in yaml_data:
                raise Exception("can't find <{}>".format(self.__moudle))
            
            # 创建句柄
            sql_conn = sqlite3.connect(db_filepath)
            cursor = sql_conn.cursor()

            sql_cmd = self.generateSqlCommand(yaml_data[self.__moudle]["node_list"])
            print("[Extract] sql_cmd: {}".format(sql_cmd))
            cursor.execute(sql_cmd)
            sql_data = cursor.fetchall()
            # print(sql_data)
            print("[Extract] find {} rows.".format(len(sql_data)))

            # 数据解析保存
            with open(output_filepath, "a+") as file:
                for row_data in sql_data:
                    node_name,log_time,save_time,log_data = row_data
                    data_json = json.loads(log_data)["log_data"]
                    str_save_data = "[{} | {}] {}  data: ".format(log_time, save_time, node_name)
                    for data_one_json in data_json:
                        str_save_data += data_one_json["data"]
                        str_save_data += " "
                    str_save_data += "\n"
                    # print(str_save_data)
                    file.write(str_save_data.encode("utf-8"))

            cursor.close()          # 关闭Cursor
            sql_conn.commit()       # 提交事务
            sql_conn.close()        # 关闭Connection     
            print("[Extract] finished. output_filepath: {}".format(output_filepath))

            
        except Exception as error:
            print("[Extract] error: {}".format(error))






if __name__ == "__main__":
    for i in range(len(sys.argv)):
        print("i: {}, argv: {}".format(i, sys.argv[i]))
    if len(sys.argv) !=4 :
        print('''please check params. such as $ python helper_logdb_extract.py alarm_manager "2023-08-16 11:12:22" "2023-08-16 11:12:23" ''')
        sys.exit(1)
    
    DbEXtract(sys.argv[1], sys.argv[2], sys.argv[3])